原帖 | Jason | 2026-08-19 11:13 | 👍1 | 阅读约1
Linux 驱动踩坑案例:compatible 匹配上,但 probe 函数完全不执行。
现象:设备树节点 compatible 和驱动of_match_table 完全对上,内核却始终不进入驱动的 probe 函数。dmesg 也没有报“no driver match”这类常规提示。
根因不在驱动代码本身,而是父总线节点的pinctrl 配置失败。
设备树里 spi/i2c 这类总线节点,一般会配置 pinctrl‑names = "default" ,用来把SCLK、MOSI、MISO 等引脚切到对应复用功能。
如果 pinctrl 配置语法写错、或者引脚被安全域/TF‑A 提前占用,会返回 ‑22 这类错误。
这个错误发生在 really_probe 内部,在调用驱动 probe 之前执行。一旦 pinctrl 获取失败, really_probe 直接返回报错,不会往下执行子设备的 probe。
关键点:比如 IMU 作为 spi bus 的子设备,哪怕 IMU 自己的 dts、驱动写的再正确,只要 spi 父节点 pinctrl 初始化失败,整条总线直接废掉,子设备根本没有机会走到自己 probe。
这里区分两种引脚申请失败场景:
1. 内核其他模块已经占用该 pin:dmesg 会打印 already requested by xxx ,很容易定位。
2. 引脚被安全域、TEE、虚拟化层提前预留:不会打印被谁占用,直接返回 ‑22,这种坑隐蔽性极高,排查难度大。
快速排查思路
1. 看 dmesg,搜 pinctrl 、 ‑22 报错,优先确认父总线(spi/i2c)节点的 pinctrl 是否初始化成功。
2. 不要只盯着子设备节点,父总线节点的pinctrl 错误,会连锁影响下面挂载的全部子设备。
3. 遇到 ‑22,没有“already requested”日志,优先怀疑:引脚被安全固件提前拿走,不是内核驱动互相抢占。
really_probe 流程里,pinctrl 的执行顺序早于设备驱动 probe,pinctrl 失败直接终止整个设备的探测流程,这个机制很多 Linux BSP 工程师容易忽略。
相关笔记
- 📁 返回本主题 MOC
- 从MCU转Linux BSP开发
- 公司名称:安华海洋智能装备(深圳)有限公司
- 嵌入式Linux调试iic
- RK3566 MIPI-CSI移植
- Linux 电容多点触摸驱动开
- 最近遇到的问题,Linux 驱动的 compatible 和设备树是匹配